package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

var db = make(map[string]string)

// 或者模拟一些私人数据
var secrets = gin.H{
	"foo":       gin.H{"email": "foo@bar.com", "phone": "123433"},
	"weiyigeek": gin.H{"email": "master@weiyigeek.top", "phone": "666"},
}

func setupRouter() *gin.Engine {
	// Disable Console Color
	// gin.DisableConsoleColor()
	r := gin.Default()

	// 1.Query 和 POST form 请求示例
	// Ping test
	r.GET("/ping", func(c *gin.Context) {
		c.String(http.StatusOK, "pong")
	})

	// 方式1.Get user value, example : /user/weiyigeek
	r.GET("/user/:name", func(c *gin.Context) {
		user := c.Params.ByName("name")
		value, ok := db[user]
		fmt.Println(user)
		if ok {
			c.JSON(http.StatusOK, gin.H{"user": user, "value": value})
		} else {
			c.JSON(http.StatusOK, gin.H{"user": user, "status": "no value"})
		}
	})

	// 方式2.Get user value, example : /username?id=1&user=weiyigeek&page=1
	r.GET("/username", func(c *gin.Context) {
		id := c.Query("id")
		user := c.Query("user")
		page := c.DefaultQuery("page", "0")
		if id != "" && user != "" || page != "" {
			c.JSON(http.StatusOK, gin.H{"code": "200", "data": gin.H{"id": id, "user": user, "page": page}})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"code": "0", "status": "err"})
		}
	})

	// 方式3.POST user value, example :
	// POST /username
	// id=1&user=weiyigeek&page=10
	r.POST("/username", func(c *gin.Context) {
		id := c.PostForm("id")
		user := c.PostForm("user")              // 表单数据
		page := c.DefaultPostForm("page", "10") // 默认值
		if secret, ok := secrets[user]; ok {
			c.JSON(http.StatusOK, gin.H{"id": id, "user": user, "page": page, "secret": secret})
		} else {
			c.JSON(http.StatusForbidden, gin.H{"user": user, "secret": "NO SECRET :("})
		}
	})

	// 路由组使用 gin.BasicAuth() 中间件设置 Auth 认证访问
	// gin.Accounts 是 map[string]string 的一种快捷方式

	// 方式1
	// authorized := r.Group("/create")
	// authorized.Use(gin.BasicAuth(gin.Credentials{
	//	  "foo":  "bar",
	//	  "weiyieek": "123456",
	//}))

	// 方式2
	authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
		"foo":       "bar",    // user:foo password:bar
		"weiyigeek": "123456", // user:manu password:123
	}))

	// admin/secrets 端点 触发 "localhost:8080/admin/secrets
	/* example curl for /admin with basicauth header
			   Zm9vOmJhcg== is base64("weiyieek:123456")
		     JS -> btoa("weiyigeek:123456") => 'd2VpeWlnZWVrOjEyMzQ1Ng=='

			curl -X POST http://localhost:8080/admin/secrets \
	-H 'authorization: Basic d2VpeWlnZWVrOjEyMzQ1Ng=='   \
	-H 'content-type: application/json'  \
	-d '{"value":"weiyigeek.top"}'
	*/
	authorized.POST("secrets", func(c *gin.Context) {
		// 获取用户，它是由 BasicAuth 中间件设置的
		user := c.MustGet(gin.AuthUserKey).(string)
		// 解析提交的JSON数据（Parse JSON）
		var json struct {
			Value string `json:"value" binding:"required"`
		}
		// 将提交的数据与对应用户绑定
		if c.Bind(&json) == nil {
			db[user] = json.Value
			c.JSON(http.StatusOK, gin.H{"status": "ok", "code": "200"})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"status": "err", "code": "0"})
		}
	})

	// POST username value
	authorized.POST("/user", func(c *gin.Context) {
		// 获取用户，它是由 BasicAuth 中间件设置的
		user := c.MustGet(gin.AuthUserKey).(string)
		// 根据authorization头，获取自定义数据
		if secret, ok := secrets[user]; ok {
			c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
		} else {
			c.JSON(http.StatusForbidden, gin.H{"user": user, "secret": "NO SECRET :("})
		}
	})

	return r
}

func main() {
	r := setupRouter()
	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}
